package com.lyx.gateway.config;

/**
 * @author 14667
 * @date 2022/7/19 9:27
 */



import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.lyx.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;


@Slf4j
@Order(-1)
@Component
public class ExceptionHandlerConfig implements ErrorWebExceptionHandler {


    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse response = exchange.getResponse();

        if (response.isCommitted()) {
            return Mono.error(ex);
        }

        // header set
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);

        byte[] bytes = exceptionResponse(ex, response).getBytes(StandardCharsets.UTF_8);
        return response
                .writeWith(Mono.fromSupplier(() -> {
                    DataBufferFactory bufferFactory = response.bufferFactory();
                    return bufferFactory.wrap(bytes);

                }));
    }

    //构建响应异常
    private String exceptionResponse(Throwable throwable, ServerHttpResponse response) {
        int code = 200;
        String msg = throwable.getMessage();
        HttpStatus status = HttpStatus.OK;
        if (throwable instanceof ResponseStatusException) {
            status = ((ResponseStatusException) throwable).getStatus();
            code = status.value();
        }else if (throwable instanceof BusinessException) {
            BusinessException exception = (BusinessException) throwable;
            status = Optional.ofNullable(HttpStatus.resolve(Integer.parseInt(exception.getCode()))).orElse(status);
            msg = exception.getMessage();

            code= Integer.parseInt(exception.getCode()) ;
        }
        response.setStatusCode(status);
        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("code", code);
        resultMap.put("message", msg);
        return JSON.toJSONString(resultMap);

    }
}

